﻿using System;
using System.Collections.Generic;
using System.Net;
using PivotServerTools;
using System.Security.Principal;
using System.Web;

namespace CollectionFactories.TeamCity
{
    internal abstract class TeamCityCollectionFactoryBase<ShowsDetailsWith> : TeamCityCollectionFactoryBase where ShowsDetailsWith : ITeamCityCollectionFactory
    {
        protected ShowsDetailsWith Inner { get; private set; }

        protected TeamCityCollectionFactoryBase(ShowsDetailsWith inner)
        {
            Inner = inner;
        }
    }

    internal abstract class TeamCityCollectionFactoryBase : ITeamCityCollectionFactory
    {
        public string ServerUrl;
        public bool Guest;
        public string UserName;
        public string Password;

        public abstract bool CanHandle(CollectionRequestContext context);

        public Collection Handle(CollectionRequestContext context)
        {
            ServerUrl = context.Query["serverUrl"];

            if (string.IsNullOrEmpty(ServerUrl))
                return ErrorCollection.FromException(new ArgumentException("You must supply a valid server url"));

            Guest = !string.IsNullOrEmpty(context.Query["guest"]);

            UserName = context.Query["username"];
            Password = context.Query["password"];

            if (!Guest && (string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(Password)))
                return
                    ErrorCollection.FromException(new ArgumentException("You must supply a valid username and password"));

            return Handle(context, GetResponseString(Resource(context)));
        }

        protected abstract Collection Handle(CollectionRequestContext context, string responseString);

        protected abstract string Resource(CollectionRequestContext context);

        protected string GetResponseString(string resource)
        {
            using (var c = new WebClient())
            {
                //c.Proxy.Credentials = new NetworkCredential("", "");

                if (!Guest)
                    c.Credentials = new NetworkCredential(UserName, Password);

                return c.DownloadString(MakeRestUri(resource));
            }
        }

        protected string MakeRestUri(string resource)
        {
            return ServerUrl + (!Guest ? "/httpAuth" : "") + string.Format("{0}", resource) + (Guest ? "?guest=1" : "");
        }

        protected string MakeUserUri(string value)
        {
            return Guest ? value + (value.Contains("?") ? "&guest=1" : "?guest=1") : value;
        }

        private static string MakeCollectionSourceUri(TeamCityAuthenticationData data, string newUrl)
        {
            newUrl += string.Format("{0}serverUrl={1}", (newUrl.Contains("?") ? "&" : "?"), data.ServerUrl);
            newUrl += data.Guest ? "&guest=1" : string.Format("&username={0}&password={1}", data.UserName, data.Password);

            return newUrl;
        }

        public string CreateCollectionUri(TeamCityAuthenticationData data, string baseUrl, string parameter)
        {
            var query = AddCollectionUrlQueryString(parameter);

            var newUrl = baseUrl;

            var separator = "?";

            foreach (var entry in query)
            {
                newUrl += string.Format("{0}{1}={2}", separator, entry.Key, entry.Value);
                separator = "&";
            }

            return MakeCollectionSourceUri(data, newUrl);
        }

        protected virtual IEnumerable<KeyValuePair<string, string>> AddCollectionUrlQueryString(string value)
        {
            yield break;
        }
    }
}